Looking at wider covid impacts data weekly variability - related to 2018/19 baseline

revised version - now extracting all Scotland more easily.

library("tidyverse")
library("janitor")
library("lubridate")
hb_codes <- read_csv("health_board_codes.csv")
Rows: 18 Columns: 5── Column specification ──────────────────────────────────────────────────────────────────
Delimiter: ","
chr (3): HB, HBName, Country
dbl (2): HBDateEnacted, HBDateArchived
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
hb_codes <- clean_names(hb_codes)

load in datafiles

weekly_admissions_spec <- read_csv("Covid admissions by health board and speciality.csv")
Rows: 55233 Columns: 11── Column specification ──────────────────────────────────────────────────────────────────
Delimiter: ","
chr (6): HB, HBQF, AdmissionType, AdmissionTypeQF, Specialty, SpecialtyQF
dbl (5): _id, WeekEnding, NumberAdmissions, Average20182019, PercentVariation
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
weekly_admissions_spec <- clean_names(weekly_admissions_spec)

weekly_admissions_dep <- read_csv("Covid admissions by health board and deprivation.csv")
Rows: 30370 Columns: 10── Column specification ──────────────────────────────────────────────────────────────────
Delimiter: ","
chr (4): HB, HBQF, AdmissionType, AdmissionTypeQF
dbl (6): _id, WeekEnding, SIMDQuintile, NumberAdmissions, Average20182019, PercentVari...
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
weekly_admissions_dep <- clean_names(weekly_admissions_dep)

weekly_admissions_demog <- read_csv("Covid admissions by health board, age and sex.csv")
Rows: 61951 Columns: 13── Column specification ──────────────────────────────────────────────────────────────────
Delimiter: ","
chr (8): HB, HBQF, AgeGroup, AgeGroupQF, Sex, SexQF, AdmissionType, AdmissionTypeQF
dbl (5): _id, WeekEnding, NumberAdmissions, Average20182019, PercentVariation
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
weekly_admissions_demog <- clean_names(weekly_admissions_demog)

data cleaning note probably more cleaning needed before we finalise I changed the spelling but it turns out both spellings are correct!

weekly_admissions_spec <- weekly_admissions_spec %>% 
  rename("speciality"= "specialty") %>% 
  rename("speciality_qf"= "specialty_qf") 

merge hbnames into datafiles

weekly_admissions_spec <- left_join(weekly_admissions_spec,hb_codes)
Joining, by = "hb"
weekly_admissions_demog <- left_join(weekly_admissions_demog,hb_codes)
Joining, by = "hb"
weekly_admissions_dep <- left_join(weekly_admissions_dep,hb_codes) 
Joining, by = "hb"

do the analysis needed for identifying qinter and ‘crisis’

weekly_admissions_spec <- weekly_admissions_spec %>% 
  mutate(year = as.integer(str_sub(week_ending,1,4))) %>% 
  mutate(month = as.integer(str_sub(week_ending,5,6))) %>% 
  mutate(day = as.integer(str_sub(week_ending,7,8))) %>% 
  mutate(wdate = ymd(week_ending)) %>% 
  # identify "All Scotland" data
  mutate(hb_name = ifelse(hb=="S92000003","All Scotland",hb_name)) %>% 
  mutate(hb_name = ifelse(is.na(hb_name),"NHS Region Unknown",hb_name)) %>% 
  mutate(iswinter = ifelse(month %in% c(4,5,6,7,8,9),FALSE,TRUE)) %>% 
  mutate(above_thresh = ifelse(percent_variation>0,7,0))
weekly_admissions_demog <- weekly_admissions_demog %>% 
  mutate(year = as.integer(str_sub(week_ending,1,4))) %>% 
  mutate(month = as.integer(str_sub(week_ending,5,6))) %>% 
  mutate(day = as.integer(str_sub(week_ending,7,8))) %>% 
  mutate(wdate = ymd(week_ending)) %>% 
  # identify "All Scotland" data
  mutate(hb_name = ifelse(hb=="S92000003","All Scotland",hb_name)) %>% 
  mutate(hb_name = ifelse(is.na(hb_name),"NHS Region Unknown",hb_name)) %>% 
  mutate(iswinter = ifelse(month %in% c(4,5,6,7,8,9),FALSE,TRUE)) %>% 
  mutate(above_thresh = ifelse(percent_variation>0,7,0))
weekly_admissions_dep <- weekly_admissions_dep %>% 
  mutate(year = as.integer(str_sub(week_ending,1,4))) %>% 
  mutate(month = as.integer(str_sub(week_ending,5,6))) %>% 
  mutate(day = as.integer(str_sub(week_ending,7,8))) %>% 
  mutate(wdate = ymd(week_ending)) %>% 
  # identify "All Scotland" data
  mutate(hb_name = ifelse(hb=="S92000003","All Scotland",hb_name)) %>% 
  mutate(hb_name = ifelse(is.na(hb_name),"NHS Region Unknown",hb_name)) %>% 
  mutate(iswinter = ifelse(month %in% c(4,5,6,7,8,9),FALSE,TRUE)) %>% 
  mutate(above_thresh = ifelse(percent_variation>0,7,0))

take a look at what is in each dataset

weekly_admissions_spec %>% 
  distinct(hb_name)

14 health boards plus ‘all scotland’ and an NA - need to work out what to do with this

weekly_admissions_spec %>% 
  distinct(admission_type)

Data neatly divided into emergency and planned

weekly_admissions_spec %>% 
  distinct(speciality)

note that some groupings are also combined. need to take a closer look at what these mean.

weekly_admissions_demog %>% 
  distinct(age_group)

7 age groups and “all ages”

weekly_admissions_demog %>% 
  distinct(sex)

just male - female and all

weekly_admissions_dep %>% 
  distinct(simd_quintile)

note there is no ‘all’ category in this dataset

plot total admissions - you should get the same overall trends from each dataset

weekly_admissions_demog %>% 
  filter(age_group == "All ages") %>% 
  filter(sex =="All") %>% 
  filter(admission_type == "All") %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = number_admissions) +
geom_line(colour='red') 

weekly_admissions_spec %>% 
  filter(speciality == "All") %>% 
  filter(admission_type == "All") %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = number_admissions) +
geom_line(colour='red') 

same graph as above!

weekly hospital admissions hover around 14000 per week expect 168,000 per quarter?

pre=pandemic hospital admissions hovered around 15500 per week expect 186,000 per quarter

weekly_admissions_spec %>% 
  filter(speciality == "All") %>% 
  filter(admission_type == "All") %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = percent_variation) +
geom_line(colour='red') 

Overall(all specialities, all admissions, all healthboards) admissions are only at 90% of pre-pandemic levels

quick look at demographics

weekly_admissions_demog %>% 
  filter(sex == "All") %>% 
  filter(age_group != "All ages") %>% 
  filter(hb_name =="All Scotland") %>% 
  filter(admission_type == "All") %>% 
ggplot() +
aes(x=wdate, y = number_admissions, color = age_group) +
geom_line() #+

#scale_colour_brewer(palette = "Set2") 

age plot shows some variation between age groups.

quick look at sex differences

weekly_admissions_demog %>% 
  filter(sex != "All") %>% 
  filter(age_group == "All ages") %>% 
  filter(hb_name =="All Scotland") %>% 
  filter(admission_type == "All") %>% 
ggplot() +
aes(x=wdate, y = percent_variation, color = sex) +
geom_line() #+

#scale_colour_brewer(palette = "Set2") 

quick look at index of deprivation. 1 is most deprived and 5 is least deprived

weekly_admissions_dep %>% 
  filter(admission_type == "All") %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = percent_variation, color = as.factor(simd_quintile)) +
geom_line() 

something happening in 2022 - why is there divergence between 1 and 5?

look at admissions type

weekly_admissions_spec %>% 
  filter(admission_type != "All") %>% 
  filter(speciality=="All") %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = percent_variation, colour = admission_type) +
geom_line()

need to check what the ‘spike’ in planned at end of 2021 is related to

quick look at specialities

weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality !="All") %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line()

take a closer look at paediatrics

weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality !="All") %>% 
  filter(str_detect(speciality,"Paed")) %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = number_admissions, colour=speciality) +
geom_line()

weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality !="All") %>% 
  filter(str_detect(speciality,"Paed")) %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line()

take a closer look at medical

weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality !="All") %>% 
  filter(str_detect(speciality,"Medical")) %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line()

simpler plot of specialities

weekly_admissions_spec %>% 
  filter(admission_type == "Planned") %>% 
  filter(speciality !="Medical (incl. Cardiology & Cancer)") %>% 
  filter(!str_detect(speciality,"Paed")) %>% 
  filter(speciality !="All") %>% 
  filter(speciality !="Accident & Emergency") %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line() +
scale_colour_brewer(palette = "Set1") 

weekly_admissions_spec %>% 
  filter(admission_type == "Emergency") %>% 
  filter(speciality !="Medical (incl. Cardiology & Cancer)") %>% 
  filter(!str_detect(speciality,"Paed")) %>% 
  filter(speciality !="All") %>% 
  filter(speciality !="Accident & Emergency") %>% 
  filter(hb_name =="All Scotland") %>% 
ggplot() +
aes(x=wdate, y = percent_variation, colour=speciality) +
geom_line() +
scale_colour_brewer(palette = "Set1") 

boxplot for different specialities? some values greater than 8000% (i have filtered them out ) indicates we need some more work on data cleaning!

weekly_admissions_spec %>% 
  #filter(admission_type == "All") %>% 
  #filter(speciality!="All") %>% 
  #filter(hb_name =="NHS Region Unknown") %>% 
  #group_by(speciality) %>% 
  #need to take a good look at what these values are!
  filter(percent_variation>500) 
weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality!="All") %>% 
  group_by(speciality) %>% 
  #need to take a good look at what these values are!
  filter(percent_variation<8000) %>% 
  ggplot()+
  aes(x=speciality, y=percent_variation)+
  geom_boxplot()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

some specialities have faced higher admission levels than others.

Now look by health boards

all_admissions_byhb <- weekly_admissions %>% 
  filter(admission_type == "All") %>% 
  filter(speciality=="All") %>% 
  group_by(hb_name) %>% 
  summarise(mean_percnt_var = mean(percent_variation),
            min_percnt_var = min(percent_variation),
            max_percnt_var = max(percent_variation)
           ) %>%
  #mutate(all_percent_variation = all_admissions/all_avg20182019)  
  arrange(desc(max_percnt_var))
all_admissions_byhb
weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality=="All") %>% 
  group_by(hb_name) %>% 
  ggplot()+
  aes(x=wdate, y=percent_variation, colour = hb_name)+
  geom_line()

weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality=="All") %>% 
  group_by(hb_name) %>% 
  ggplot()+
  aes(x=hb_name, y=percent_variation)+
  geom_boxplot()+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

for some health boards a significant number of admissions levels are above the levels seen in 2018-19. could we parhaps try and use this as an indicator?

Need to think more carefully about what the data in ‘region unknown’ means

weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality=="All") %>% 
  ggplot() +
  aes(x=wdate, y=percent_variation, colour=hb_name) +
  geom_line()+
  facet_wrap(~hb_name)

How is NA calculated - still need to check??

weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality == "All") %>% 
  filter(hb_name != "All Scotland") %>% 
ggplot() +
aes(x=wdate, y = number_admissions, colour = hb_name) +
geom_line()

admission values shows all health boards - health boards vary massively in size and admission numbers but mostly same overall pattern.

weekly_admissions_spec %>% 
  filter(admission_type == "All") %>% 
  filter(speciality=="Accident & Emergency") %>% 
  #take a good look at what these values are!
  filter(percent_variation<8000) %>% 
  group_by(hb_name) %>% 
  ggplot()+
  aes(x=hb_name, y=percent_variation)+
  geom_boxplot() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

do only certain health boards have an A+E dept?

weekly_admissions_spec %>% 
  filter(admission_type == "Emergency") %>% 
  #filter(speciality=="Accident & Emergency") %>% 
  #take a good look at what these values are!
  filter(percent_variation<8000) %>% 
  group_by(hb_name) %>% 
  ggplot()+
  aes(x=hb_name, y=percent_variation)+
  geom_boxplot() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

first attempt at a ‘crisis’ calculation

weekly_admissions %>% 
  filter(admission_type == "All") %>% 
  filter(speciality=="All") %>% 
  #filter(admission_type =="Emergency") %>% 
  #filter(speciality=="Accident & Emergency") %>% 
  #filter(year == 2020) %>% 
  filter(iswinter) %>%
  group_by(hb_name) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>%
  ggplot() +
  aes(x=hb_name, y=mean_percentvar) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

weekly_admissions_spec %>% 
  filter(speciality=="All") %>% 
  filter(admission_type =="All") %>% 
  #filter(year == 2021) %>% 
  #filter(iswinter) %>%
  group_by(hb_name) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>%
  ggplot() +
  aes(x=hb_name, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

weekly_admissions_spec %>% 
  filter(speciality=="All") %>% 
  filter(admission_type =="Emergency") %>% 
  #filter(speciality=="Accident & Emergency") %>% 
  #filter(year == 2020) %>% 
  filter(iswinter) %>%
  group_by(hb_name) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>%
  ggplot() +
  aes(x=hb_name, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

take a look by health board

weekly_admissions_spec %>% 
  filter(speciality=="All") %>% 
  filter(admission_type =="Emergency") %>% 
  #filter(speciality=="Accident & Emergency") %>% 
  #filter(year == 2020) %>% 
  #filter(iswinter) %>%
  group_by(hb_name) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>%
  ggplot() +
  aes(x=hb_name, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

quick look at winter v summer

weekly_admissions_spec %>% 
  filter(speciality=="Accident & Emergency") %>% 
  filter(admission_type =="All") %>% 
  group_by(iswinter, year) %>% 
  summarise(pcnt_bad_days = sum(above_thresh)/n()*7, mean_percentvar =mean(percent_variation)) 
`summarise()` has grouped output by 'iswinter'. You can override using the `.groups` argument.

no obvious big discrepancy in winter admissions for this parameter winters of 2020 and 2022 are ‘worse’ than summers, percentages are small and maybe not significant?

weekly_admissions_spec %>% 
  filter(speciality=="All") %>% 
  filter(admission_type =="All") %>% 
  group_by(iswinter, year) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>% 
  ggplot() +
  aes(x=iswinter, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  facet_grid(~year)
`summarise()` has grouped output by 'iswinter'. You can override using the `.groups` argument.

weekly_admissions_spec %>% 
  filter(speciality=="All") %>% 
  filter(admission_type =="Emergency") %>% 
  group_by(iswinter, year) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>% 
  ggplot() +
  aes(x=iswinter, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  facet_grid(~year)
`summarise()` has grouped output by 'iswinter'. You can override using the `.groups` argument.

weekly_admissions_spec %>% 
  filter(speciality=="Accident & Emergency") %>% 
  filter(admission_type =="Emergency") %>% 
  group_by(iswinter, year) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>% 
  ggplot() +
  aes(x=year, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  facet_grid(~iswinter)
`summarise()` has grouped output by 'iswinter'. You can override using the `.groups` argument.

#Section2 - repeat for demographic data

bad days by age group

weekly_admissions_demog %>% 
  filter(sex=="All") %>% 
  filter(admission_type =="All") %>% 
  filter(hb_name=="All Scotland") %>% 
  #filter(year == "2021") %>% 
  #filter(iswinter) %>% 
  group_by(age_group) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar = mean(percent_variation), 
            #trying a diff calc just to show its the same
            percent_variation = 100*(sum(number_admissions)-sum(average20182019))
                             /sum(average20182019)) 
weekly_admissions_spec %>% 
  filter(speciality !="All") %>% 
  filter(admission_type =="All") %>% 
  filter(hb_name == "All Scotland") %>% 
  group_by(speciality) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>% 
  ggplot() +
  aes(x=speciality, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) 

weekly_admissions_demog %>% 
  filter(sex=="All") %>% 
  filter(admission_type =="All") %>% 
  filter(hb_name=="All Scotland") %>% 
  group_by(age_group) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>% 
  ggplot() +
  aes(x=age_group, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) 

weekly_admissions_demog %>% 
  filter(age_group=="All ages") %>% 
  filter(admission_type =="All") %>% 
  filter(hb_name=="All Scotland") %>% 
  group_by(sex) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>% 
  ggplot() +
  aes(x=sex, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

no obvious difference between sexes

weekly_admissions_dep %>% 
  filter(admission_type =="All") %>% 
  filter(hb_name=="All Scotland") %>% 
  group_by(simd_quintile, year) %>% 
  summarise(count_bad_days = sum(above_thresh), 
            count_days = n()*7, 
            pcnt_bad_days = 100*(sum(above_thresh)/(n()*7)), 
            mean_percentvar =mean(percent_variation)) %>% 
  ggplot() +
  aes(x=simd_quintile, y=pcnt_bad_days) +
  geom_col() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) + 
  facet_grid(~year)
`summarise()` has grouped output by 'simd_quintile'. You can override using the `.groups` argument.

LS0tCnRpdGxlOiAiSW52ZXN0aWdhdGluZyBEYXRhIC0gQ292aWQgV2lkZXIgSW1wYWN0cyIKb3V0cHV0OiBodG1sX25vdGVib29rCmVkaXRvcl9vcHRpb25zOiAKICBjaHVua19vdXRwdXRfdHlwZTogaW5saW5lCi0tLQoKTG9va2luZyBhdCB3aWRlciBjb3ZpZCBpbXBhY3RzIGRhdGEKd2Vla2x5IHZhcmlhYmlsaXR5IC0gcmVsYXRlZCB0byAyMDE4LzE5IGJhc2VsaW5lCgpyZXZpc2VkIHZlcnNpb24gLSBub3cgZXh0cmFjdGluZyBhbGwgU2NvdGxhbmQgbW9yZSBlYXNpbHkuCgpgYGB7cn0KbGlicmFyeSgidGlkeXZlcnNlIikKbGlicmFyeSgiamFuaXRvciIpCmxpYnJhcnkoImx1YnJpZGF0ZSIpCmBgYAoKYGBge3J9CmhiX2NvZGVzIDwtIHJlYWRfY3N2KCJoZWFsdGhfYm9hcmRfY29kZXMuY3N2IikKaGJfY29kZXMgPC0gY2xlYW5fbmFtZXMoaGJfY29kZXMpCmBgYAoKbG9hZCBpbiBkYXRhZmlsZXMKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjIDwtIHJlYWRfY3N2KCJDb3ZpZCBhZG1pc3Npb25zIGJ5IGhlYWx0aCBib2FyZCBhbmQgc3BlY2lhbGl0eS5jc3YiKQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjIDwtIGNsZWFuX25hbWVzKHdlZWtseV9hZG1pc3Npb25zX3NwZWMpCgp3ZWVrbHlfYWRtaXNzaW9uc19kZXAgPC0gcmVhZF9jc3YoIkNvdmlkIGFkbWlzc2lvbnMgYnkgaGVhbHRoIGJvYXJkIGFuZCBkZXByaXZhdGlvbi5jc3YiKQp3ZWVrbHlfYWRtaXNzaW9uc19kZXAgPC0gY2xlYW5fbmFtZXMod2Vla2x5X2FkbWlzc2lvbnNfZGVwKQoKd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgPC0gcmVhZF9jc3YoIkNvdmlkIGFkbWlzc2lvbnMgYnkgaGVhbHRoIGJvYXJkLCBhZ2UgYW5kIHNleC5jc3YiKQp3ZWVrbHlfYWRtaXNzaW9uc19kZW1vZyA8LSBjbGVhbl9uYW1lcyh3ZWVrbHlfYWRtaXNzaW9uc19kZW1vZykKYGBgCgpkYXRhIGNsZWFuaW5nCm5vdGUgcHJvYmFibHkgbW9yZSBjbGVhbmluZyBuZWVkZWQgYmVmb3JlIHdlIGZpbmFsaXNlCkkgY2hhbmdlZCB0aGUgc3BlbGxpbmcgYnV0IGl0IHR1cm5zIG91dCBib3RoIHNwZWxsaW5ncyBhcmUgY29ycmVjdCEKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjIDwtIHdlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIHJlbmFtZSgic3BlY2lhbGl0eSI9ICJzcGVjaWFsdHkiKSAlPiUgCiAgcmVuYW1lKCJzcGVjaWFsaXR5X3FmIj0gInNwZWNpYWx0eV9xZiIpIApgYGAKCm1lcmdlIGhibmFtZXMgaW50byBkYXRhZmlsZXMKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgPC0gbGVmdF9qb2luKHdlZWtseV9hZG1pc3Npb25zX3NwZWMsaGJfY29kZXMpCndlZWtseV9hZG1pc3Npb25zX2RlbW9nIDwtIGxlZnRfam9pbih3ZWVrbHlfYWRtaXNzaW9uc19kZW1vZyxoYl9jb2RlcykKd2Vla2x5X2FkbWlzc2lvbnNfZGVwIDwtIGxlZnRfam9pbih3ZWVrbHlfYWRtaXNzaW9uc19kZXAsaGJfY29kZXMpIApgYGAKCmRvIHRoZSBhbmFseXNpcyBuZWVkZWQgZm9yIGlkZW50aWZ5aW5nIHFpbnRlciBhbmQgJ2NyaXNpcycKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjIDwtIHdlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIG11dGF0ZSh5ZWFyID0gYXMuaW50ZWdlcihzdHJfc3ViKHdlZWtfZW5kaW5nLDEsNCkpKSAlPiUgCiAgbXV0YXRlKG1vbnRoID0gYXMuaW50ZWdlcihzdHJfc3ViKHdlZWtfZW5kaW5nLDUsNikpKSAlPiUgCiAgbXV0YXRlKGRheSA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZyw3LDgpKSkgJT4lIAogIG11dGF0ZSh3ZGF0ZSA9IHltZCh3ZWVrX2VuZGluZykpICU+JSAKICAjIGlkZW50aWZ5ICJBbGwgU2NvdGxhbmQiIGRhdGEKICBtdXRhdGUoaGJfbmFtZSA9IGlmZWxzZShoYj09IlM5MjAwMDAwMyIsIkFsbCBTY290bGFuZCIsaGJfbmFtZSkpICU+JSAKICBtdXRhdGUoaGJfbmFtZSA9IGlmZWxzZShpcy5uYShoYl9uYW1lKSwiTkhTIFJlZ2lvbiBVbmtub3duIixoYl9uYW1lKSkgJT4lIAogIG11dGF0ZShpc3dpbnRlciA9IGlmZWxzZShtb250aCAlaW4lIGMoNCw1LDYsNyw4LDkpLEZBTFNFLFRSVUUpKSAlPiUgCiAgbXV0YXRlKGFib3ZlX3RocmVzaCA9IGlmZWxzZShwZXJjZW50X3ZhcmlhdGlvbj4wLDcsMCkpCmBgYAoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX2RlbW9nIDwtIHdlZWtseV9hZG1pc3Npb25zX2RlbW9nICU+JSAKICBtdXRhdGUoeWVhciA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZywxLDQpKSkgJT4lIAogIG11dGF0ZShtb250aCA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZyw1LDYpKSkgJT4lIAogIG11dGF0ZShkYXkgPSBhcy5pbnRlZ2VyKHN0cl9zdWIod2Vla19lbmRpbmcsNyw4KSkpICU+JSAKICBtdXRhdGUod2RhdGUgPSB5bWQod2Vla19lbmRpbmcpKSAlPiUgCiAgIyBpZGVudGlmeSAiQWxsIFNjb3RsYW5kIiBkYXRhCiAgbXV0YXRlKGhiX25hbWUgPSBpZmVsc2UoaGI9PSJTOTIwMDAwMDMiLCJBbGwgU2NvdGxhbmQiLGhiX25hbWUpKSAlPiUgCiAgbXV0YXRlKGhiX25hbWUgPSBpZmVsc2UoaXMubmEoaGJfbmFtZSksIk5IUyBSZWdpb24gVW5rbm93biIsaGJfbmFtZSkpICU+JSAKICBtdXRhdGUoaXN3aW50ZXIgPSBpZmVsc2UobW9udGggJWluJSBjKDQsNSw2LDcsOCw5KSxGQUxTRSxUUlVFKSkgJT4lIAogIG11dGF0ZShhYm92ZV90aHJlc2ggPSBpZmVsc2UocGVyY2VudF92YXJpYXRpb24+MCw3LDApKQpgYGAKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19kZXAgPC0gd2Vla2x5X2FkbWlzc2lvbnNfZGVwICU+JSAKICBtdXRhdGUoeWVhciA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZywxLDQpKSkgJT4lIAogIG11dGF0ZShtb250aCA9IGFzLmludGVnZXIoc3RyX3N1Yih3ZWVrX2VuZGluZyw1LDYpKSkgJT4lIAogIG11dGF0ZShkYXkgPSBhcy5pbnRlZ2VyKHN0cl9zdWIod2Vla19lbmRpbmcsNyw4KSkpICU+JSAKICBtdXRhdGUod2RhdGUgPSB5bWQod2Vla19lbmRpbmcpKSAlPiUgCiAgIyBpZGVudGlmeSAiQWxsIFNjb3RsYW5kIiBkYXRhCiAgbXV0YXRlKGhiX25hbWUgPSBpZmVsc2UoaGI9PSJTOTIwMDAwMDMiLCJBbGwgU2NvdGxhbmQiLGhiX25hbWUpKSAlPiUgCiAgbXV0YXRlKGhiX25hbWUgPSBpZmVsc2UoaXMubmEoaGJfbmFtZSksIk5IUyBSZWdpb24gVW5rbm93biIsaGJfbmFtZSkpICU+JSAKICBtdXRhdGUoaXN3aW50ZXIgPSBpZmVsc2UobW9udGggJWluJSBjKDQsNSw2LDcsOCw5KSxGQUxTRSxUUlVFKSkgJT4lIAogIG11dGF0ZShhYm92ZV90aHJlc2ggPSBpZmVsc2UocGVyY2VudF92YXJpYXRpb24+MCw3LDApKQpgYGAKCnRha2UgYSBsb29rIGF0IHdoYXQgaXMgaW4gZWFjaCBkYXRhc2V0CgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZGlzdGluY3QoaGJfbmFtZSkKYGBgCjE0IGhlYWx0aCBib2FyZHMgcGx1cyAnYWxsIHNjb3RsYW5kJyBhbmQgYW4gTkEgLSBuZWVkIHRvIHdvcmsgb3V0IHdoYXQgdG8gZG8gd2l0aCB0aGlzCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZGlzdGluY3QoYWRtaXNzaW9uX3R5cGUpCmBgYApEYXRhIG5lYXRseSBkaXZpZGVkIGludG8gZW1lcmdlbmN5IGFuZCBwbGFubmVkCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBkaXN0aW5jdChzcGVjaWFsaXR5KQpgYGAKbm90ZSB0aGF0IHNvbWUgZ3JvdXBpbmdzIGFyZSBhbHNvIGNvbWJpbmVkLiBuZWVkIHRvIHRha2UgYSBjbG9zZXIgbG9vayBhdCB3aGF0IHRoZXNlIG1lYW4uCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGRpc3RpbmN0KGFnZV9ncm91cCkKYGBgCjcgYWdlIGdyb3VwcyBhbmQgImFsbCBhZ2VzIgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX2RlbW9nICU+JSAKICBkaXN0aW5jdChzZXgpCmBgYApqdXN0IG1hbGUgLSBmZW1hbGUgYW5kIGFsbAoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX2RlcCAlPiUgCiAgZGlzdGluY3Qoc2ltZF9xdWludGlsZSkKYGBgCm5vdGUgdGhlcmUgaXMgbm8gJ2FsbCcgY2F0ZWdvcnkgaW4gdGhpcyBkYXRhc2V0CgpwbG90IHRvdGFsIGFkbWlzc2lvbnMgLSB5b3Ugc2hvdWxkIGdldCB0aGUgc2FtZSBvdmVyYWxsIHRyZW5kcyBmcm9tIGVhY2ggZGF0YXNldApgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihhZ2VfZ3JvdXAgPT0gIkFsbCBhZ2VzIikgJT4lIAogIGZpbHRlcihzZXggPT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihoYl9uYW1lID09IkFsbCBTY290bGFuZCIpICU+JSAKZ2dwbG90KCkgKwphZXMoeD13ZGF0ZSwgeSA9IG51bWJlcl9hZG1pc3Npb25zKSArCmdlb21fbGluZShjb2xvdXI9J3JlZCcpIApgYGAKCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBudW1iZXJfYWRtaXNzaW9ucykgKwpnZW9tX2xpbmUoY29sb3VyPSdyZWQnKSAKYGBgCnNhbWUgZ3JhcGggYXMgYWJvdmUhCgp3ZWVrbHkgaG9zcGl0YWwgYWRtaXNzaW9ucyBob3ZlciBhcm91bmQgMTQwMDAgcGVyIHdlZWsKZXhwZWN0IDE2OCwwMDAgcGVyIHF1YXJ0ZXI/CgpwcmU9cGFuZGVtaWMgaG9zcGl0YWwgYWRtaXNzaW9ucyBob3ZlcmVkIGFyb3VuZCAxNTUwMCBwZXIgd2VlawpleHBlY3QgMTg2LDAwMCBwZXIgcXVhcnRlcgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWUgPT0iQWxsIFNjb3RsYW5kIikgJT4lIApnZ3Bsb3QoKSArCmFlcyh4PXdkYXRlLCB5ID0gcGVyY2VudF92YXJpYXRpb24pICsKZ2VvbV9saW5lKGNvbG91cj0ncmVkJykgCmBgYAoKT3ZlcmFsbChhbGwgc3BlY2lhbGl0aWVzLCBhbGwgYWRtaXNzaW9ucywgYWxsIGhlYWx0aGJvYXJkcykgYWRtaXNzaW9ucyBhcmUgb25seSBhdCA5MCUgb2YgcHJlLXBhbmRlbWljIGxldmVscwoKCnF1aWNrIGxvb2sgYXQgZGVtb2dyYXBoaWNzCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihzZXggPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoYWdlX2dyb3VwICE9ICJBbGwgYWdlcyIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBudW1iZXJfYWRtaXNzaW9ucywgY29sb3IgPSBhZ2VfZ3JvdXApICsKZ2VvbV9saW5lKCkgIysKI3NjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikgCmBgYAphZ2UgcGxvdCBzaG93cyBzb21lIHZhcmlhdGlvbiBiZXR3ZWVuIGFnZSBncm91cHMuCgpxdWljayBsb29rIGF0IHNleCBkaWZmZXJlbmNlcwpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihzZXggIT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoYWdlX2dyb3VwID09ICJBbGwgYWdlcyIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3IgPSBzZXgpICsKZ2VvbV9saW5lKCkgIysKI3NjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikgCmBgYAoKcXVpY2sgbG9vayBhdCBpbmRleCBvZiBkZXByaXZhdGlvbi4gMSBpcyBtb3N0IGRlcHJpdmVkIGFuZCA1IGlzIGxlYXN0IGRlcHJpdmVkCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVwICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3IgPSBhcy5mYWN0b3Ioc2ltZF9xdWludGlsZSkpICsKZ2VvbV9saW5lKCkgCmBgYApzb21ldGhpbmcgaGFwcGVuaW5nIGluIDIwMjIgLSB3aHkgaXMgdGhlcmUgZGl2ZXJnZW5jZSBiZXR3ZWVuIDEgYW5kIDU/CgoKCmxvb2sgYXQgYWRtaXNzaW9ucyB0eXBlCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgIT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFsbCIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3VyID0gYWRtaXNzaW9uX3R5cGUpICsKZ2VvbV9saW5lKCkKYGBgCm5lZWQgdG8gY2hlY2sgd2hhdCB0aGUgJ3NwaWtlJyBpbiBwbGFubmVkIGF0IGVuZCBvZiAyMDIxIGlzIHJlbGF0ZWQgdG8KCnF1aWNrIGxvb2sgYXQgc3BlY2lhbGl0aWVzCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eSAhPSJBbGwiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWUgPT0iQWxsIFNjb3RsYW5kIikgJT4lIApnZ3Bsb3QoKSArCmFlcyh4PXdkYXRlLCB5ID0gcGVyY2VudF92YXJpYXRpb24sIGNvbG91cj1zcGVjaWFsaXR5KSArCmdlb21fbGluZSgpCmBgYAp0YWtlIGEgY2xvc2VyIGxvb2sgYXQgcGFlZGlhdHJpY3MKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9IkFsbCIpICU+JSAKICBmaWx0ZXIoc3RyX2RldGVjdChzcGVjaWFsaXR5LCJQYWVkIikpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBudW1iZXJfYWRtaXNzaW9ucywgY29sb3VyPXNwZWNpYWxpdHkpICsKZ2VvbV9saW5lKCkKYGBgCgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9IkFsbCIpICU+JSAKICBmaWx0ZXIoc3RyX2RldGVjdChzcGVjaWFsaXR5LCJQYWVkIikpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3VyPXNwZWNpYWxpdHkpICsKZ2VvbV9saW5lKCkKYGBgCnRha2UgYSBjbG9zZXIgbG9vayBhdCBtZWRpY2FsCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkgIT0iQWxsIikgJT4lIAogIGZpbHRlcihzdHJfZGV0ZWN0KHNwZWNpYWxpdHksIk1lZGljYWwiKSkgJT4lIAogIGZpbHRlcihoYl9uYW1lID09IkFsbCBTY290bGFuZCIpICU+JSAKZ2dwbG90KCkgKwphZXMoeD13ZGF0ZSwgeSA9IHBlcmNlbnRfdmFyaWF0aW9uLCBjb2xvdXI9c3BlY2lhbGl0eSkgKwpnZW9tX2xpbmUoKQpgYGAKc2ltcGxlciBwbG90IG9mIHNwZWNpYWxpdGllcwpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJQbGFubmVkIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9Ik1lZGljYWwgKGluY2wuIENhcmRpb2xvZ3kgJiBDYW5jZXIpIikgJT4lIAogIGZpbHRlcighc3RyX2RldGVjdChzcGVjaWFsaXR5LCJQYWVkIikpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eSAhPSJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkgIT0iQWNjaWRlbnQgJiBFbWVyZ2VuY3kiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWUgPT0iQWxsIFNjb3RsYW5kIikgJT4lIApnZ3Bsb3QoKSArCmFlcyh4PXdkYXRlLCB5ID0gcGVyY2VudF92YXJpYXRpb24sIGNvbG91cj1zcGVjaWFsaXR5KSArCmdlb21fbGluZSgpICsKc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSAKYGBgCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJFbWVyZ2VuY3kiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkgIT0iTWVkaWNhbCAoaW5jbC4gQ2FyZGlvbG9neSAmIENhbmNlcikiKSAlPiUgCiAgZmlsdGVyKCFzdHJfZGV0ZWN0KHNwZWNpYWxpdHksIlBhZWQiKSkgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9IkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eSAhPSJBY2NpZGVudCAmIEVtZXJnZW5jeSIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZSA9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCmdncGxvdCgpICsKYWVzKHg9d2RhdGUsIHkgPSBwZXJjZW50X3ZhcmlhdGlvbiwgY29sb3VyPXNwZWNpYWxpdHkpICsKZ2VvbV9saW5lKCkgKwpzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpIApgYGAKYm94cGxvdCBmb3IgZGlmZmVyZW50IHNwZWNpYWxpdGllcz8gc29tZSB2YWx1ZXMgZ3JlYXRlciB0aGFuIDgwMDAlIChpIGhhdmUgZmlsdGVyZWQgdGhlbSBvdXQgKSBpbmRpY2F0ZXMgd2UgbmVlZCBzb21lIG1vcmUgd29yayBvbiBkYXRhIGNsZWFuaW5nIQoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogICNmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICAjZmlsdGVyKHNwZWNpYWxpdHkhPSJBbGwiKSAlPiUgCiAgI2ZpbHRlcihoYl9uYW1lID09Ik5IUyBSZWdpb24gVW5rbm93biIpICU+JSAKICAjZ3JvdXBfYnkoc3BlY2lhbGl0eSkgJT4lIAogICNuZWVkIHRvIHRha2UgYSBnb29kIGxvb2sgYXQgd2hhdCB0aGVzZSB2YWx1ZXMgYXJlIQogIGZpbHRlcihwZXJjZW50X3ZhcmlhdGlvbj41MDApIApgYGAKCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHkhPSJBbGwiKSAlPiUgCiAgZ3JvdXBfYnkoc3BlY2lhbGl0eSkgJT4lIAogICNuZWVkIHRvIHRha2UgYSBnb29kIGxvb2sgYXQgd2hhdCB0aGVzZSB2YWx1ZXMgYXJlIQogIGZpbHRlcihwZXJjZW50X3ZhcmlhdGlvbjw4MDAwKSAlPiUgCiAgZ2dwbG90KCkrCiAgYWVzKHg9c3BlY2lhbGl0eSwgeT1wZXJjZW50X3ZhcmlhdGlvbikrCiAgZ2VvbV9ib3hwbG90KCkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCnNvbWUgc3BlY2lhbGl0aWVzIGhhdmUgZmFjZWQgaGlnaGVyIGFkbWlzc2lvbiBsZXZlbHMgdGhhbiBvdGhlcnMuCgoKTm93IGxvb2sgYnkgaGVhbHRoIGJvYXJkcyAKCmBgYHtyfQphbGxfYWRtaXNzaW9uc19ieWhiIDwtIHdlZWtseV9hZG1pc3Npb25zICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFsbCIpICU+JSAKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgc3VtbWFyaXNlKG1lYW5fcGVyY250X3ZhciA9IG1lYW4ocGVyY2VudF92YXJpYXRpb24pLAogICAgICAgICAgICBtaW5fcGVyY250X3ZhciA9IG1pbihwZXJjZW50X3ZhcmlhdGlvbiksCiAgICAgICAgICAgIG1heF9wZXJjbnRfdmFyID0gbWF4KHBlcmNlbnRfdmFyaWF0aW9uKQogICAgICAgICAgICkgJT4lCiAgI211dGF0ZShhbGxfcGVyY2VudF92YXJpYXRpb24gPSBhbGxfYWRtaXNzaW9ucy9hbGxfYXZnMjAxODIwMTkpICAKICBhcnJhbmdlKGRlc2MobWF4X3BlcmNudF92YXIpKQphbGxfYWRtaXNzaW9uc19ieWhiCmBgYApgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHk9PSJBbGwiKSAlPiUgCiAgZ3JvdXBfYnkoaGJfbmFtZSkgJT4lIAogIGdncGxvdCgpKwogIGFlcyh4PXdkYXRlLCB5PXBlcmNlbnRfdmFyaWF0aW9uLCBjb2xvdXIgPSBoYl9uYW1lKSsKICBnZW9tX2xpbmUoKQpgYGAKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkFsbCIpICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFsbCIpICU+JSAKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgZ2dwbG90KCkrCiAgYWVzKHg9aGJfbmFtZSwgeT1wZXJjZW50X3ZhcmlhdGlvbikrCiAgZ2VvbV9ib3hwbG90KCkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgoKZm9yIHNvbWUgaGVhbHRoIGJvYXJkcyBhIHNpZ25pZmljYW50IG51bWJlciBvZiBhZG1pc3Npb25zIGxldmVscyBhcmUgYWJvdmUgdGhlIGxldmVscyBzZWVuIGluIDIwMTgtMTkuIGNvdWxkIHdlIHBhcmhhcHMgdHJ5IGFuZCB1c2UgdGhpcyBhcyBhbiBpbmRpY2F0b3I/CgpOZWVkIHRvIHRoaW5rIG1vcmUgY2FyZWZ1bGx5IGFib3V0IHdoYXQgdGhlIGRhdGEgaW4gJ3JlZ2lvbiB1bmtub3duJyBtZWFucyAKCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHk9PSJBbGwiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4PXdkYXRlLCB5PXBlcmNlbnRfdmFyaWF0aW9uLCBjb2xvdXI9aGJfbmFtZSkgKwogIGdlb21fbGluZSgpKwogIGZhY2V0X3dyYXAofmhiX25hbWUpCmBgYApIb3cgaXMgTkEgY2FsY3VsYXRlZCAtIHN0aWxsIG5lZWQgdG8gY2hlY2s/PwoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ID09ICJBbGwiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWUgIT0gIkFsbCBTY290bGFuZCIpICU+JSAKZ2dwbG90KCkgKwphZXMoeD13ZGF0ZSwgeSA9IG51bWJlcl9hZG1pc3Npb25zLCBjb2xvdXIgPSBoYl9uYW1lKSArCmdlb21fbGluZSgpCmBgYAphZG1pc3Npb24gdmFsdWVzIHNob3dzIGFsbCBoZWFsdGggYm9hcmRzIC0gaGVhbHRoIGJvYXJkcyB2YXJ5IG1hc3NpdmVseSBpbiBzaXplIGFuZCBhZG1pc3Npb24gbnVtYmVycyBidXQgbW9zdGx5IHNhbWUgb3ZlcmFsbCBwYXR0ZXJuLgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWNjaWRlbnQgJiBFbWVyZ2VuY3kiKSAlPiUgCiAgI3Rha2UgYSBnb29kIGxvb2sgYXQgd2hhdCB0aGVzZSB2YWx1ZXMgYXJlIQogIGZpbHRlcihwZXJjZW50X3ZhcmlhdGlvbjw4MDAwKSAlPiUgCiAgZ3JvdXBfYnkoaGJfbmFtZSkgJT4lIAogIGdncGxvdCgpKwogIGFlcyh4PWhiX25hbWUsIHk9cGVyY2VudF92YXJpYXRpb24pKwogIGdlb21fYm94cGxvdCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKZG8gb25seSBjZXJ0YWluIGhlYWx0aCBib2FyZHMgaGF2ZSBhbiBBK0UgZGVwdD8KCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0gIkVtZXJnZW5jeSIpICU+JSAKICAjZmlsdGVyKHNwZWNpYWxpdHk9PSJBY2NpZGVudCAmIEVtZXJnZW5jeSIpICU+JSAKICAjdGFrZSBhIGdvb2QgbG9vayBhdCB3aGF0IHRoZXNlIHZhbHVlcyBhcmUhCiAgZmlsdGVyKHBlcmNlbnRfdmFyaWF0aW9uPDgwMDApICU+JSAKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgZ2dwbG90KCkrCiAgYWVzKHg9aGJfbmFtZSwgeT1wZXJjZW50X3ZhcmlhdGlvbikrCiAgZ2VvbV9ib3hwbG90KCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKZmlyc3QgYXR0ZW1wdCBhdCBhICdjcmlzaXMnIGNhbGN1bGF0aW9uCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnMgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSAiQWxsIikgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWxsIikgJT4lIAogICNmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iRW1lcmdlbmN5IikgJT4lIAogICNmaWx0ZXIoc3BlY2lhbGl0eT09IkFjY2lkZW50ICYgRW1lcmdlbmN5IikgJT4lIAogICNmaWx0ZXIoeWVhciA9PSAyMDIwKSAlPiUgCiAgZmlsdGVyKGlzd2ludGVyKSAlPiUKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50X2JhZF9kYXlzID0gc3VtKGFib3ZlX3RocmVzaCksIAogICAgICAgICAgICBjb3VudF9kYXlzID0gbigpKjcsIAogICAgICAgICAgICBwY250X2JhZF9kYXlzID0gMTAwKihzdW0oYWJvdmVfdGhyZXNoKS8obigpKjcpKSwgCiAgICAgICAgICAgIG1lYW5fcGVyY2VudHZhciA9bWVhbihwZXJjZW50X3ZhcmlhdGlvbikpICU+JQogIGdncGxvdCgpICsKICBhZXMoeD1oYl9uYW1lLCB5PW1lYW5fcGVyY2VudHZhcikgKwogIGdlb21fY29sKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJBbGwiKSAlPiUgCiAgI2ZpbHRlcih5ZWFyID09IDIwMjEpICU+JSAKICAjZmlsdGVyKGlzd2ludGVyKSAlPiUKICBncm91cF9ieShoYl9uYW1lKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50X2JhZF9kYXlzID0gc3VtKGFib3ZlX3RocmVzaCksIAogICAgICAgICAgICBjb3VudF9kYXlzID0gbigpKjcsIAogICAgICAgICAgICBwY250X2JhZF9kYXlzID0gMTAwKihzdW0oYWJvdmVfdGhyZXNoKS8obigpKjcpKSwgCiAgICAgICAgICAgIG1lYW5fcGVyY2VudHZhciA9bWVhbihwZXJjZW50X3ZhcmlhdGlvbikpICU+JQogIGdncGxvdCgpICsKICBhZXMoeD1oYl9uYW1lLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJFbWVyZ2VuY3kiKSAlPiUgCiAgI2ZpbHRlcihzcGVjaWFsaXR5PT0iQWNjaWRlbnQgJiBFbWVyZ2VuY3kiKSAlPiUgCiAgI2ZpbHRlcih5ZWFyID09IDIwMjApICU+JSAKICBmaWx0ZXIoaXN3aW50ZXIpICU+JQogIGdyb3VwX2J5KGhiX25hbWUpICU+JSAKICBzdW1tYXJpc2UoY291bnRfYmFkX2RheXMgPSBzdW0oYWJvdmVfdGhyZXNoKSwgCiAgICAgICAgICAgIGNvdW50X2RheXMgPSBuKCkqNywgCiAgICAgICAgICAgIHBjbnRfYmFkX2RheXMgPSAxMDAqKHN1bShhYm92ZV90aHJlc2gpLyhuKCkqNykpLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50dmFyID1tZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSkgJT4lCiAgZ2dwbG90KCkgKwogIGFlcyh4PWhiX25hbWUsIHk9cGNudF9iYWRfZGF5cykgKwogIGdlb21fY29sKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAp0YWtlIGEgbG9vayBieSBoZWFsdGggYm9hcmQKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFsbCIpICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iRW1lcmdlbmN5IikgJT4lIAogICNmaWx0ZXIoc3BlY2lhbGl0eT09IkFjY2lkZW50ICYgRW1lcmdlbmN5IikgJT4lIAogICNmaWx0ZXIoeWVhciA9PSAyMDIwKSAlPiUgCiAgI2ZpbHRlcihpc3dpbnRlcikgJT4lCiAgZ3JvdXBfYnkoaGJfbmFtZSkgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAlPiUKICBnZ3Bsb3QoKSArCiAgYWVzKHg9aGJfbmFtZSwgeT1wY250X2JhZF9kYXlzKSArCiAgZ2VvbV9jb2woKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgoKcXVpY2sgbG9vayBhdCB3aW50ZXIgdiBzdW1tZXIKCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFjY2lkZW50ICYgRW1lcmdlbmN5IikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJBbGwiKSAlPiUgCiAgZ3JvdXBfYnkoaXN3aW50ZXIsIHllYXIpICU+JSAKICBzdW1tYXJpc2UocGNudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpL24oKSo3LCBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAKYGBgCiAgbm8gb2J2aW91cyBiaWcgZGlzY3JlcGFuY3kgaW4gd2ludGVyIGFkbWlzc2lvbnMgZm9yIHRoaXMgcGFyYW1ldGVyCiAgd2ludGVycyBvZiAyMDIwIGFuZCAyMDIyIGFyZSAnd29yc2UnIHRoYW4gc3VtbWVycywgcGVyY2VudGFnZXMgYXJlIHNtYWxsIGFuZCBtYXliZSBub3QgICAgICAgICAgc2lnbmlmaWNhbnQ/IAoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5PT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJBbGwiKSAlPiUgCiAgZ3JvdXBfYnkoaXN3aW50ZXIsIHllYXIpICU+JSAKICBzdW1tYXJpc2UoY291bnRfYmFkX2RheXMgPSBzdW0oYWJvdmVfdGhyZXNoKSwgCiAgICAgICAgICAgIGNvdW50X2RheXMgPSBuKCkqNywgCiAgICAgICAgICAgIHBjbnRfYmFkX2RheXMgPSAxMDAqKHN1bShhYm92ZV90aHJlc2gpLyhuKCkqNykpLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50dmFyID1tZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSkgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeD1pc3dpbnRlciwgeT1wY250X2JhZF9kYXlzKSArCiAgZ2VvbV9jb2woKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkgKwogIGZhY2V0X2dyaWQofnllYXIpCmBgYApgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfc3BlYyAlPiUgCiAgZmlsdGVyKHNwZWNpYWxpdHk9PSJBbGwiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09IkVtZXJnZW5jeSIpICU+JSAKICBncm91cF9ieShpc3dpbnRlciwgeWVhcikgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4PWlzd2ludGVyLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgZmFjZXRfZ3JpZCh+eWVhcikKYGBgCmBgYHtyfQp3ZWVrbHlfYWRtaXNzaW9uc19zcGVjICU+JSAKICBmaWx0ZXIoc3BlY2lhbGl0eT09IkFjY2lkZW50ICYgRW1lcmdlbmN5IikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJFbWVyZ2VuY3kiKSAlPiUgCiAgZ3JvdXBfYnkoaXN3aW50ZXIsIHllYXIpICU+JSAKICBzdW1tYXJpc2UoY291bnRfYmFkX2RheXMgPSBzdW0oYWJvdmVfdGhyZXNoKSwgCiAgICAgICAgICAgIGNvdW50X2RheXMgPSBuKCkqNywgCiAgICAgICAgICAgIHBjbnRfYmFkX2RheXMgPSAxMDAqKHN1bShhYm92ZV90aHJlc2gpLyhuKCkqNykpLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50dmFyID1tZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSkgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeD15ZWFyLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArCiAgZmFjZXRfZ3JpZCh+aXN3aW50ZXIpCmBgYAoKCiNTZWN0aW9uMiAtIHJlcGVhdCBmb3IgZGVtb2dyYXBoaWMgZGF0YQoKYmFkIGRheXMgYnkgYWdlIGdyb3VwCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihzZXg9PSJBbGwiKSAlPiUgCiAgZmlsdGVyKGFkbWlzc2lvbl90eXBlID09IkFsbCIpICU+JSAKICBmaWx0ZXIoaGJfbmFtZT09IkFsbCBTY290bGFuZCIpICU+JSAKICAjZmlsdGVyKHllYXIgPT0gIjIwMjEiKSAlPiUgCiAgI2ZpbHRlcihpc3dpbnRlcikgJT4lIAogIGdyb3VwX2J5KGFnZV9ncm91cCkgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPSBtZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSwgCiAgICAgICAgICAgICN0cnlpbmcgYSBkaWZmIGNhbGMganVzdCB0byBzaG93IGl0cyB0aGUgc2FtZQogICAgICAgICAgICBwZXJjZW50X3ZhcmlhdGlvbiA9IDEwMCooc3VtKG51bWJlcl9hZG1pc3Npb25zKS1zdW0oYXZlcmFnZTIwMTgyMDE5KSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvc3VtKGF2ZXJhZ2UyMDE4MjAxOSkpIApgYGAKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX3NwZWMgJT4lIAogIGZpbHRlcihzcGVjaWFsaXR5ICE9IkFsbCIpICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iQWxsIikgJT4lIAogIGZpbHRlcihoYl9uYW1lID09ICJBbGwgU2NvdGxhbmQiKSAlPiUgCiAgZ3JvdXBfYnkoc3BlY2lhbGl0eSkgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4PXNwZWNpYWxpdHksIHk9cGNudF9iYWRfZGF5cykgKwogIGdlb21fY29sKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpIApgYGAKCgoKYGBge3J9CndlZWtseV9hZG1pc3Npb25zX2RlbW9nICU+JSAKICBmaWx0ZXIoc2V4PT0iQWxsIikgJT4lIAogIGZpbHRlcihhZG1pc3Npb25fdHlwZSA9PSJBbGwiKSAlPiUgCiAgZmlsdGVyKGhiX25hbWU9PSJBbGwgU2NvdGxhbmQiKSAlPiUgCiAgZ3JvdXBfYnkoYWdlX2dyb3VwKSAlPiUgCiAgc3VtbWFyaXNlKGNvdW50X2JhZF9kYXlzID0gc3VtKGFib3ZlX3RocmVzaCksIAogICAgICAgICAgICBjb3VudF9kYXlzID0gbigpKjcsIAogICAgICAgICAgICBwY250X2JhZF9kYXlzID0gMTAwKihzdW0oYWJvdmVfdGhyZXNoKS8obigpKjcpKSwgCiAgICAgICAgICAgIG1lYW5fcGVyY2VudHZhciA9bWVhbihwZXJjZW50X3ZhcmlhdGlvbikpICU+JSAKICBnZ3Bsb3QoKSArCiAgYWVzKHg9YWdlX2dyb3VwLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSAKYGBgCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVtb2cgJT4lIAogIGZpbHRlcihhZ2VfZ3JvdXA9PSJBbGwgYWdlcyIpICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iQWxsIikgJT4lIAogIGZpbHRlcihoYl9uYW1lPT0iQWxsIFNjb3RsYW5kIikgJT4lIAogIGdyb3VwX2J5KHNleCkgJT4lIAogIHN1bW1hcmlzZShjb3VudF9iYWRfZGF5cyA9IHN1bShhYm92ZV90aHJlc2gpLCAKICAgICAgICAgICAgY291bnRfZGF5cyA9IG4oKSo3LCAKICAgICAgICAgICAgcGNudF9iYWRfZGF5cyA9IDEwMCooc3VtKGFib3ZlX3RocmVzaCkvKG4oKSo3KSksIAogICAgICAgICAgICBtZWFuX3BlcmNlbnR2YXIgPW1lYW4ocGVyY2VudF92YXJpYXRpb24pKSAlPiUgCiAgZ2dwbG90KCkgKwogIGFlcyh4PXNleCwgeT1wY250X2JhZF9kYXlzKSArCiAgZ2VvbV9jb2woKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCm5vIG9idmlvdXMgZGlmZmVyZW5jZSBiZXR3ZWVuIHNleGVzCgpgYGB7cn0Kd2Vla2x5X2FkbWlzc2lvbnNfZGVwICU+JSAKICBmaWx0ZXIoYWRtaXNzaW9uX3R5cGUgPT0iQWxsIikgJT4lIAogIGZpbHRlcihoYl9uYW1lPT0iQWxsIFNjb3RsYW5kIikgJT4lIAogIGdyb3VwX2J5KHNpbWRfcXVpbnRpbGUsIHllYXIpICU+JSAKICBzdW1tYXJpc2UoY291bnRfYmFkX2RheXMgPSBzdW0oYWJvdmVfdGhyZXNoKSwgCiAgICAgICAgICAgIGNvdW50X2RheXMgPSBuKCkqNywgCiAgICAgICAgICAgIHBjbnRfYmFkX2RheXMgPSAxMDAqKHN1bShhYm92ZV90aHJlc2gpLyhuKCkqNykpLCAKICAgICAgICAgICAgbWVhbl9wZXJjZW50dmFyID1tZWFuKHBlcmNlbnRfdmFyaWF0aW9uKSkgJT4lIAogIGdncGxvdCgpICsKICBhZXMoeD1zaW1kX3F1aW50aWxlLCB5PXBjbnRfYmFkX2RheXMpICsKICBnZW9tX2NvbCgpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArIAogIGZhY2V0X2dyaWQofnllYXIpCmBgYA==